package com.nut.spp.util;

import cn.hutool.core.util.URLUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.nut.spp.entity.SysFile;
import com.nut.spp.enums.FilePathEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;

/**
 * 新版oss工具
 */
@Data
@Slf4j
@Component
public class OSSUtil {

    //阿里云 ACCESSKEYID
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;

    //阿里云 ACCESSKEYSECRET
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;

    //OSS EndPoint
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    //OSS Bucket
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    //  访问域名前缀
    @Value("${aliyun.oss.urlPrefix}")
    private String urlPrefix;

    private OSS ossClient;

    @PostConstruct
    public void init() {
        ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    /**
     * 上传文件
     * @param file
     * @param filePathEnum
     * @return
     * @throws IOException
     */
    public SysFile uploadFile(MultipartFile file, FilePathEnum filePathEnum) throws IOException {

        String fileName = file.getOriginalFilename();
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();

        InputStream inputStream = file.getInputStream();

        return uploadInputStream(inputStream, filePathEnum, ext);
    }

    /**
     * 上传url资源
     * @param url
     * @param filePathEnum
     * @param ext
     * @return SysFile
     * @author guohaibin
     * @date 2022/8/11 17:34
     */
    public SysFile uploadUrl(String url, FilePathEnum filePathEnum, String ext) {

        InputStream inputStream = URLUtil.getStream(URLUtil.url(url));

        return uploadInputStream(inputStream, filePathEnum, ext);
    }

    /**
     * 流上传
     * @param inputStream
     * @param filePathEnum
     * @param ext
     * @return SysFile
     * @author guohaibin
     * @date 2022/8/27 16:15
     */
    public SysFile uploadInputStream(InputStream inputStream, FilePathEnum filePathEnum, String ext) {

        StringBuilder sb = new StringBuilder(50);
        sb.append(filePathEnum.getDir()).append("/").append(IdUtil.uuid()).append(".").append(ext);
        String fileName = sb.toString();

        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(getContentType(ext));

        ossClient.putObject(bucketName, fileName, inputStream, metadata);

//        String fileUrl = getUrlPrefix() + fileName;
        String fileUrl = urlPrefix + fileName;
        log.info("file_url=" + fileUrl);

        SysFile sysFile = new SysFile();
        sysFile.setName(fileName);
        sysFile.setUrl(fileUrl);
        sysFile.setExt(ext);

        return sysFile;
    }

    /**
     * 删除文件
     * @param objectName
     * @return void
     * @author guohaibin
     * @date 2022/9/3 16:04
     */
    public void delete(String objectName) {
        ossClient.deleteObject(bucketName, objectName);
    }

    private String getUrlPrefix() {
        return "https://" + bucketName + "." + endpoint + "/";
    }

    /**
     * 根据文件类型获取ContentType
     * @param fileType
     * @return String
     */
    private String getContentType(String fileType) {
        fileType = fileType.toLowerCase();
        String contentType;
        switch (fileType) {
            case "bmp":
                contentType = "image/bmp";
                break;
            case "gif":
                contentType = "image/gif";
                break;
            case "png":
            case "jpeg":
            case "jpg":
                contentType = "image/jpeg";
                break;
            case "html":
                contentType = "text/html";
                break;
            case "txt":
                contentType = "text/plain";
                break;
            case "vsd":
                contentType = "application/vnd.visio";
                break;
            case "ppt":
            case "pptx":
                contentType = "application/vnd.ms-powerpoint";
                break;
            case "doc":
            case "docx":
                contentType = "application/msword";
                break;
            case "xml":
                contentType = "text/xml";
                break;
            case "mp4":
                contentType = "video/mp4";
                break;
            default:
                contentType = "application/octet-stream";
                break;
        }
        return contentType;
    }

}

